from __future__ import print_function
import os
import subprocess
import random
import time

from threading import Thread
# from queue import Queue

# ===== compress cmds =========
# rmvb -> wav {in} {out}
cmd_wav = 'ffmpeg -i {}  -vn -c:a pcm_s16le -y -f wav {}'
# wav -> aac {in} {out}
cmd_nero = 'neroAacEnc -br {} -2pass -if {} -of {}'
# cmd2 = 'neroAacEnc -q 0.8 -ignorelength -2pass -if {} -of {}'
# rmvb-> mp4 {out} {in}
cmd_x264 = 'x264 --threads auto --crf 26 --preset 6 --subme 10 --ref 9 --bframes 14 --b-adapt 2 --qcomp 0.55 --psy-rd 0:0 --keyint 360 --min-keyint 1 --aq-strength 0.9 --aq-mode 3 -o {} {}'
# --vf resize:960,720,,,,lanczos
cmd3_x264_resize = ' --vf resize:{},{},,,,lanczos'
# aac+mp4 -> mp4
cmd_copy = 'ffmpeg -i {} -i {} -c copy -y {}'

# =========== fragment and dash ==============
cmd_resize  = 'ffmpeg -i {} -c copy -s {w}x{h} -y {}'
# {in} {out}
cmd_fragment = 'mp4fragment --fragment-duration automatic {} {}'
# -o {output dir}
cmd_dash = 'mp4dash -f --no-split --profiles=on-demand -o {} {}'

cmd_ffmpeg_info = 'ffmpeg -i {}'

'''
mp4fragment --fragment-duration 10000 1.mp4 1.frag.mp4
mp4fragment --fragment-duration 10000 2.mp4 2.frag.mp4
mp4dash -f --no-split --profiles=on-demand 1.frag.mp4 2.frag.mp4
'''

def read_stream_as_lines(stream ,line_sep=['\n'] , line_cb=None):
	line = ''
	lines = []
	while True :
		b = stream.read(1)
		if not b :
			break
		if b in line_sep :
			if line_cb:
				line_cb(line)
			lines.append(line.strip())
			line = ''
		line +=b
	return lines
def stdoutFunc(stdout ,line_sep=['\n']) :
	lines = read_stream_as_lines(stdout,line_sep)
	print(lines)
	# with open('log.txt','w+') as f:
	# 	for i , v in enumerate(lines):
	# 		f.write(str(i)+":"+v+'\n')
	# time.sleep(1)
	# print(lines)
		# line = stdout.readline()
		# if not line :
		# 	break
		# print('line' ,line )
	# print("done",stdout.name)

def exe_cmd(cmd):
	output = os.popen(cmd)
	r = output.read()
	print(r)
	# print("cmd:" ,cmd)
	# return subprocess.call(cmd,shell=True)
def run_cmd(cmd , *args , **kwargs) :
	p = subprocess.Popen(cmd,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE , universal_newlines=True)
	t = Thread(target=stdoutFunc,args=(p.stdout,))
	t1 = Thread(target=stdoutFunc,args=(p.stderr,))
	
	t.start()
	t1.start()
	p.wait()
	t.join()
	t1.join()
# run_cmd('ffmpeg')

# resolutions:[[w,h]]
def compress(input_file,output_file ,resolutions=None, audio_br=191500,max_audio_br=191500):
	dirpath , file_name = os.path.split(input_file)
	name,ext = os.path.splitext(file_name)
	file_wav = os.path.join(dirpath , name+'.wav')
	file_aac = os.path.join(dirpath ,name+'.aac')
	file_tmp_mp4 = os.path.join(dirpath ,name+'_tmp.mp4')
	file_tmp_res_mp4 = os.path.join(dirpath ,name+'{}x{}_tmp.mp4')
	audio_br = int(audio_br)
	if audio_br > max_audio_br :
		audio_br = max_audio_br

	r = exe_cmd(cmd_wav.format(input_file,file_wav))
	# print(r.returncode)
	r = exe_cmd(cmd_nero.format(audio_br,file_wav,file_aac))
	if not resolutions:
		r = exe_cmd(cmd_x264.format(file_tmp_mp4,input_file))
		os.remove(file_tmp_mp4)
		return [output_file]
	else :
		output_files = [] 
		for w,h in resolutions:
			tmp_mp4 = file_tmp_res_mp4.format(w,h)
			out_file = append_size(output_file , w,h)
			r = exe_cmd((cmd_x264+cmd3_x264_resize).format(tmp_mp4,input_file , w,h))
			r = exe_cmd(cmd_copy.format(tmp_mp4,file_aac,out_file))
			os.remove(tmp_mp4)
			output_files.append(out_file)
		return output_files
	os.remove(file_wav)
	os.remove(file_aac)
	# run_cmd(cmd3.format(file_tmp_mp4,input_file))
	
def append_filename(file_name , name):
	f , e = os.path.splitext(file_name)
	return f+name+e

def append_size(file_name , w,h):
	return append_filename(file_name,'.{}x{}'.format(w,h))

def resize(src_file , dst_file , size , threads=8):
	cmd = 'ffmpeg -i {} -y -s {} -threads {} {}'
	exe_cmd(cmd.format(src_file,size,threads,dst_file))

def dash(src_files):
	cwd = os.path.dirname(src_files[0])
	# {in} {out}
	cmd1 = 'mp4fragment --fragment-duration 10000 {} {}'
	frags = []
	for sf in src_files :
		frag = append_filename(sf , "_frag")
		frags.append(frag)
		exe_cmd(cmd1.format(sf , frag))
	cmd2 = 'mp4dash -f --no-split --profiles=on-demand -o {} {}'
	exe_cmd(cmd2.format(cwd,' '.join(frags)))
	for f in frags:
		os.remove(f)
	# exe_cmd('mp4dash --help')


def clip(src_file ,dst_file,ss='00:00:00',duration=30):
	cmd = 'ffmpeg -ss {ss} -t {duration} -accurate_seek -i {src_file} -codec copy -y -avoid_negative_ts 1 {dst_file}'
	r = exe_cmd(cmd.format(src_file=src_file,dst_file=dst_file,ss=ss,duration=duration))
	return r

def snapshot(src_file,dst_file ,ss=30):
	ss = ss + random.randint(0,60)
	cmd='ffmpeg -i {src_file} -v quiet -y -f image2 -ss {ss} -vframes 1 {dst_file}'
	r = exe_cmd(cmd.format(src_file=src_file,dst_file=dst_file,ss=ss))
	return r


import json
prob='ffprobe -v quiet -print_format json -show_format -show_streams {}'
def get_video_info(video_file):
	output = os.popen(prob.format(video_file) )
	r = output.read()
	print(r)
	# print(r.stdout)
	# print(r.stdout.decode('utf-8'))
	video_info = json.loads(r)
	streams = {s['codec_type'] : s for s in video_info['streams']}
	format = video_info['format']

	return streams,format
	# print(video_info)


# streams , format = get_video_info('d:/data/1.wmv')
# print(streams['audio']['bit_rate'])https://gitee.com/hellozaza/good.git
# print(format)

# compress('d:/data/1_clip.wmv','d:/data/1_clip.mp4' ,audio_br=streams['audio']['bit_rate'])
# get_video_info('d:/data/1.mp4')

# clip('d:/data/1.wmv' , 'd:/data/1_clip.wmv')
# snapshot('d:/data/1.mp4' , 'd:/data/1.jpg')

# f ='d:/data/video/1_clip.mp4'
# f1 = append_filename(f , '480p')
# streams , format = get_video_info(f)
# abi = streams['audio']['bit_rate']
# compress(f,f1,640,480 , abi)
# dash(src_files=[f,f1])

# run_cmd("ffmpeg")

# print(append_size('hello.mp4' , 2,3))


r = compress("d:/data/video/1_clip.mp4" , "d:/data/video/1_clip.mp4",resolutions=[[100,100],[200,200]])
print(r)
'''
848*480 : 179417+189278 = 374519
1024*768: 43328+64163 = 112100

333584=48024+272000
413536=214071 + 189613
'''


# clip('d:/data/1.wmv','d:/data/1_clip.wmv' , 50 , 60)


